package io.zhiller.simpletemplate.api.file_operation

import android.content.Context
import android.util.Log
import io.ktor.client.plugins.onDownload
import io.ktor.client.plugins.timeout
import io.ktor.client.request.prepareGet
import io.ktor.client.statement.bodyAsChannel
import io.ktor.util.cio.writeChannel
import io.ktor.utils.io.copyTo
import io.zhiller.simpletemplate.api.httpClient
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import java.io.File
import kotlin.time.Duration.Companion.minutes

object FileApis {
  suspend fun downloadFile(
    context: Context,
    downloadUrl: String = "",
    saveFile: File? = null,
    onProcess: (progress: Int, alreadyDownloadedSize: Long) -> Unit = { _, _ -> },
  ): Flow<DownloadFileStatus> = flow {
    // 获取APK文件的下载URL
//    val downloadUrl =
//      "https://gitee.com/zhillerdev_compose_samples/dev-template-basic/releases/download/v1.0.0-beta1/document.docx"
    Log.i("Apis", "download file: $downloadUrl")
    val saveFileTemp = saveFile ?: File(context.getExternalFilesDir("temp"), "temp_file.zip")
    emit(DownloadFileStatus.INITIAL)
    try {
      emit(DownloadFileStatus.PROGRESS)
      httpClient.prepareGet(urlString = downloadUrl, block = {
        val timeout = 30.minutes.inWholeMilliseconds
        timeout {
          requestTimeoutMillis = timeout
          connectTimeoutMillis = timeout
          socketTimeoutMillis = timeout
        }
        var counter = 0L
        onDownload { bytesSentTotal, contentLength ->
          val totalSize = contentLength ?: 1
          counter++
          if (counter == 50L) {
//            Log.i("dev", "downloadFileWithProgress: $bytesSentTotal/$contentLength")
            counter = 0L
          }
          if (bytesSentTotal == totalSize) {
            onProcess(100, totalSize)
          } else {
            val cur = ((bytesSentTotal.toFloat() / totalSize.toFloat()) * 100f).toInt()
//            Log.i("dev", "downloadFile: $cur")
            onProcess(cur, bytesSentTotal)
          }
        }
      }).execute { response ->
        if (response.status.value in 200..299) {
          val byteReadChannel = response.bodyAsChannel()
          byteReadChannel.copyTo(saveFileTemp.writeChannel())
        } else {
          Log.e("App", "Failed to download file. HTTP Status: ${response.status.value}")
          saveFileTemp.delete()
        }
      }
    } catch (e: Exception) {
      // 如果下载过程中发生异常，记录错误信息
      Log.e("UpdateUtil", "Failed to download the apk", e)
      emit(DownloadFileStatus.FAILED("err"))
    }
    
    Log.i("dev", "downloadFile: download complete")
    emit(DownloadFileStatus.COMPLETED(saveFileTemp.absolutePath, saveFileTemp.name))
  }
}
